﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DSPL.Contracts.ViewModel;
using System.Collections.ObjectModel;
using DSPL.Contracts.Command;
using System.Windows.Input;
using System.Data;
using DSPL.Contracts.Common;
using DSPL.Contracts.Interfaces;
using System.Diagnostics;
using System.Windows;
using DSPL.Common.Classes;

namespace DSPL.Common.ViewModel
{
    public class FilterWindowViewModel : BaseViewModel
    {
        public FilterWindowViewModel(ObservableCollection<ColumnValueProperties> columnList)
        {
            ColumnList = columnList;
            ConnectorList = new ObservableCollection<ColumnValueProperties> { new ColumnValueProperties() { DispalyMember = "And" }, new ColumnValueProperties() { DispalyMember = "Or" } };
            FilterData = new ObservableCollection<FilterStringProperties>() { new FilterStringProperties() };

        }

        Window parentWindow;

        private bool isFilterValueFocus;

        public bool IsFilterValueFocus
        {
            get { return isFilterValueFocus; }
            set { isFilterValueFocus = value;
            this.OnPropertyChanged("IsFilterValueFocus");
            }
        }

        private bool isFilterConnectorFocus;

        public bool IsFilterConnectorFocus
        {
            get { return isFilterConnectorFocus; }
            set
            {
                isFilterConnectorFocus = value;
                this.OnPropertyChanged("IsFilterConnectorFocus");
            }
        }

        public string FilterString { get; set; }

        private ICommand formLoad;

        public ICommand FormLoad
        {
            get
            {
                if (this.formLoad == null)
                    this.formLoad = new RelayCommand(FormLoadExecuted);
                return this.formLoad;
            }
            set { formLoad = value; }
        }

        private ICommand selectCommand;

        public ICommand SelectCommand
        {
            get
            {
                if (this.selectCommand == null)
                    this.selectCommand = new RelayCommand(SelectCommandExecute);
                return this.selectCommand;
            }
            set { selectCommand = value; }
        }

        private void FormLoadExecuted(object obj)
        {
            if (obj != null)
            {
                parentWindow = (Window)obj;
                parentWindow.Title = "Filtering Options";
            }
        }

        private void SelectCommandExecute(object obj)
        {
            if (FilterData.Count != 0 && FilterData != null)
            {
                foreach (FilterStringProperties item in FilterData)
                {
                    if (!string.IsNullOrEmpty(item.FilterKey) && !string.IsNullOrEmpty(item.FilterEquation))
                    {
                        string filterKey = item.FilterKey;
                        string filterEquation = item.FilterEquation;
                        string dataType = string.IsNullOrEmpty(item.FilterKey)?"":(ColumnList.Where(d => d.ValueMember == item.FilterKey)).FirstOrDefault().DataType.ToString();
                        object filterValue = item.FilterValue;
                        FilterString = FilterString + GenerateEquation(filterKey, filterEquation, dataType, filterValue);
                    }
                    if (FilterData.Count > 1)
                    {
                        FilterString = FilterString + " " + item.FilterConnector + " ";
                    }
                }                
            }
            if (parentWindow != null)
                parentWindow.Close();
        }

        private ICommand closeCommand;

        public ICommand CloseCommand
        {
            get
            {
                if (this.closeCommand == null)
                    this.closeCommand = new RelayCommand(CloseCommandExecuted);
                return this.closeCommand;
            }
            set { closeCommand = value; }
        }

        private void CloseCommandExecuted(object obj)
        {
            var window = obj as Window;
            if (window != null)
                window.Close();
        }

        private string GenerateEquation(string filterKey, string filterEquation, string dataType, object filterValue=null)
        {
            switch (dataType)
            {
                case "STRING":
                    filterValue = " '" + filterValue + "' ";
                    break;

                //case "DATETIME":
                //    filterValue = " '" + filterValue + "' ";                    
                //    break;

                case "DBNULL":
                    filterValue = DBNull.Value;
                    break;
            }

            string Equation = "";
            
            switch (dataType)
            {
                case "DATETIME":
                    DateTime fromDate = DateTime.Parse(filterValue.ToString());
                    DateTime toDate = (DateTime.Parse(filterValue.ToString())).AddDays(1);

                    switch (filterEquation)
                    {
                        case "equal to":
                            Equation = filterKey + " >= #" + fromDate + "# and " + filterKey + " < #" + toDate + "#";
                            break;

                        case "not equal to":
                            Equation = filterKey + " < #" + fromDate + "# and " + filterKey + " > #" + toDate + "#";
                            break;

                        case "greater than":
                            Equation = filterKey + " >= #" + toDate + "#";
                            break;

                        case "greater or equal to":
                            Equation = filterKey + " >= #" + fromDate + "#";
                            break;

                        case "less than":
                            Equation = filterKey + " < #" + fromDate + "#";
                            break;

                        case "less or equal to":
                            Equation = filterKey + " < #" + toDate + "#";
                            break;

                       case "in":
                            Equation = filterKey + " in (#" + fromDate + "#)";
                            break;

                        case "not in":
                            Equation = filterKey + " not in (#" + fromDate + "#)";
                            break;

                        default:
                            break;
                    }
                    break;

                default:
                    filterValue = filterValue.ToString().Trim();
                    switch (filterEquation)
                    {
                        case "equal to":
                            Equation = filterKey + " = " + filterValue;
                            break;

                        case "not equal to":
                            Equation = filterKey + " <> " + filterValue;
                            break;

                        case "greater than":
                            Equation = filterKey + " > " + filterValue;
                            break;

                        case "greater or equal to":
                            Equation = filterKey + " >= " + filterValue;
                            break;

                        case "less than":
                            Equation = filterKey + " < " + filterValue;
                            break;

                        case "less or equal to":
                            Equation = filterKey + " <= " + filterValue;
                            break;

                       case "in":
                            Equation = filterKey + " in (" + filterValue + ")";
                            break;

                        case "not in":
                            Equation = filterKey + " not in (" + filterValue + ")";
                            break;

                        case "begins with":
                            filterValue = filterValue.ToString().Contains("'") ? filterValue.ToString().Replace("'", "") : filterValue;
                            Equation = filterKey + " like '" + filterValue + "%'";
                            break;

                        case "does not begin with":
                            filterValue = filterValue.ToString().Contains("'") ? filterValue.ToString().Replace("'", "") : filterValue;
                            Equation = filterKey + " not like '" + filterValue + "%'";
                            break;

                        case "is like":
                            filterValue = filterValue.ToString().Contains("'") ? filterValue.ToString().Replace("'", "") : filterValue;
                            Equation = filterKey + " like '%" + filterValue + "%'";
                            break;

                        case "is not like":
                            filterValue = filterValue.ToString().Contains("'") ? filterValue.ToString().Replace("'", "") : filterValue;
                            Equation = filterKey + " not like '%" + filterValue + "%'";
                            break;

                        case "contains":
                            filterValue = filterValue.ToString().Contains("'") ? filterValue.ToString().Replace("'", "") : filterValue;
                            Equation = filterKey + " like '%" + filterValue + "%'";
                            break;

                        case "does not contain":
                            filterValue = filterValue.ToString().Contains("'") ? filterValue.ToString().Replace("'", "") : filterValue;
                            Equation = filterKey + " not like '%" + filterValue + "%'";
                            break;

                        case "is empty (blank)":
                            Equation = filterKey + " = ''";
                            break;

                        case "is not empty":
                            Equation = filterKey + " <> ''";
                            break;

                        case "is true":
                            Equation = filterKey + " = 1";
                            break;

                        case "is false":
                            Equation = filterKey + " = 0";
                            break;

                        default:
                            break;
                    }
                    break;

            }
            

            return Equation;
        }

        

       


        private string displayedFilterKey;

        public string DisplayedFilterKey
        {
            get { return displayedFilterKey; }
            set { displayedFilterKey = value; }
        }
        
        private ObservableCollection<ColumnValueProperties> _ColumnList;
        public ObservableCollection<ColumnValueProperties> ColumnList
        {
            get
            {
                return _ColumnList;
            }
            set
            {
                _ColumnList = value;
                OnPropertyChanged("ColumnList");
            }
        }



        private ObservableCollection<ColumnValueProperties> _ConnectorList;
        public ObservableCollection<ColumnValueProperties> ConnectorList
        {
            get
            {
                return _ConnectorList;
            }
            set
            {
                _ConnectorList = value;
                OnPropertyChanged("ConnectorList");
            }
        }

        private ObservableCollection<FilterStringProperties> _FilterData;
        public ObservableCollection<FilterStringProperties> FilterData
        {
            get { return _FilterData; }
            set
            {
                _FilterData = value;
                OnPropertyChanged("FilterData");                
            }
        }


        private string valueStringFormat;

        public string ValueStringFormat
        {
            get { return valueStringFormat; }
            set { valueStringFormat = value;
            OnPropertyChanged("ValueStringFormat");
            }
        }
        

    }     

    public class FilterStringProperties : BaseViewModel
    {
        private string filterKey;
        private object filterValue;
        private string filterEquation;
        private string filterConnector;

        public string FilterKey
        {
            get
            {
                return filterKey;
            }
            set
            {
                filterKey = value;
                OnPropertyChanged("FilterKey");
            }
        }

        public object FilterValue
        {
            get { return filterValue; }
            set
            {
                filterValue = value;
                OnPropertyChanged("FilterValue");
            }
        }

        public string FilterEquation
        {
            get { return filterEquation; }
            set
            {
                filterEquation = value;
                OnPropertyChanged("FilterEquation");
            }
        }

        public string FilterConnector
        {
            get { return filterConnector; }
            set
            {
                filterConnector = value;
                OnPropertyChanged("FilterConnector");
            }
        }
        private ColumnValueProperties selectedFilterKey;

        public ColumnValueProperties SelectedFilterKey
        {
            get { return selectedFilterKey; }
            set
            {
                selectedFilterKey = value;
                OnPropertyChanged("SelectedFilterKey");
                FilterKeyChangedExecute();
            }
        }


        private ObservableCollection<ColumnValueProperties> _EquationList;
        public ObservableCollection<ColumnValueProperties> EquationList
        {
            get
            {
                return _EquationList;
            }
            set
            {
                _EquationList = value;
                OnPropertyChanged("EquationList");
            }
        }

        public FilterStringProperties()
        {
            EquationList = new ObservableCollection<ColumnValueProperties> { new ColumnValueProperties() };    
        }

        public FilterStringProperties(string filterKey, string filterValue, string filterEquation)
        {
            this.FilterKey = filterKey;
            this.FilterValue = filterValue;
            this.FilterEquation = filterEquation;
            EquationList = new ObservableCollection<ColumnValueProperties> { new ColumnValueProperties() };   
        }

        public FilterStringProperties(string filterKey, string filterValue, string filterEquation, string filterConnector)
        {
            this.FilterKey = filterKey;
            this.FilterValue = filterValue;
            this.FilterEquation = filterEquation;
            this.FilterConnector = filterConnector;
            EquationList = new ObservableCollection<ColumnValueProperties> { new ColumnValueProperties() };   
        }

        private void FilterKeyChangedExecute()
        {
            if (SelectedFilterKey != null)
            {
                EquationList.Clear();
                if (SelectedFilterKey.DataType == "STRING")
                {
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "not equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "greater than" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "greater or equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "less than" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "less or equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "contains" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "does not contain" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "in" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "not in" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "begins with" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "does not begin with" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "is like" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "is not like" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "is empty (blank)" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "is not empty" });
                }
                if (SelectedFilterKey.DataType.Substring(0, 3) == "INT" || SelectedFilterKey.DataType == "DECIMAL" || SelectedFilterKey.DataType == "DATETIME")
                {
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "not equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "greater than" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "greater or equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "less than" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "less or equal to" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "in" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "not in" });
                }
                if (SelectedFilterKey.DataType == "BOOLEAN")
                {
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "is true" });
                    EquationList.Add(new ColumnValueProperties() { DispalyMember = "is false" });
                }
            }
        }
    }
}
